#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
#ifdef __linux__
#include <dlfcn.h>
#include <unistd.h> 
#ifdef __cplusplus
#define ASAPI extern "C" __attribute__((visibility("default"),noinline))
#else
#define ASAPI __attribute__((visibility("default"),noinline))
#endif

#ifdef ASCENE_CORE_VERSION
#define ASCENE_API_FUNCTION __attribute__((visibility("default"),noinline))
	typedef ::AScene::Machine* asMachine;
	typedef ::AScene::AllTypeData* asValue;
#else
#define ASCENE_API_FUNCTION
	typedef void* asMachine;
	typedef void* asValue;
#endif 

#else
#ifdef _WIN32
#ifdef __cplusplus
#define ASAPI extern "C" __declspec(dllexport)
#else
#define ASAPI __declspec(dllexport)
#endif
#ifdef ASCENE_CORE_VERSION
#define ASCENE_API_FUNCTION __declspec(dllexport)
	typedef ::AScene::Machine* asMachine;
	typedef ::AScene::AllTypeData* asValue;
#else
#define ASCENE_API_FUNCTION __declspec(dllimport)
	typedef void* asMachine;
	typedef void* asValue;
#endif 


#else
#error 暂时不支持其他操作系统
#endif

#endif


#define AS_REAL_TYPE (0)
#define AS_HANDLE_TYPE (1)
#define AS_STRING_TYPE (2)
#define AS_STRUCT_TYPE (3)

#define AS_COROUTINE_CONTINUE ((asValue*)(0x01))

	typedef int asInt;
	typedef int asEnum;
	typedef long long asLong;
	typedef double asDouble;
	typedef const char* asString;
	typedef int asBool;

	//初始化ASCENE运行环境
	ASCENE_API_FUNCTION void asInit(asInt, char**);

	//创建ASCENE虚拟机
	ASCENE_API_FUNCTION asMachine asCreateMachine(asInt);

	//销毁ASCENE虚拟机
	ASCENE_API_FUNCTION void asDestroyMachine(asMachine);

	//导出ASCENE虚拟机储存的字节码
	ASCENE_API_FUNCTION asString asBuildBytecode(asMachine);

	//加载ASCENE源代码,并运行初始化代码,返回值为0表示正常，否则表示异常。
	ASCENE_API_FUNCTION asInt asLoadSource(asMachine, asString);

	//从文件加载ASCENE源代码,并运行初始化代码,返回值为0表示正常，否则表示异常。
	ASCENE_API_FUNCTION asInt asLoadFile(asMachine, asString);

	//获取ASCENE给出的最后一条错误信息
	ASCENE_API_FUNCTION asString asGetLastError();

	//获取ASCENE虚拟机给出的最后一条错误信息
	ASCENE_API_FUNCTION asString asGetError(asMachine);

	//运行ASCENE虚拟机,从main函数处运行代码,返回值为main函数的返回值，若返回NULL，则说明运行时出现未处理的异常
	ASCENE_API_FUNCTION asValue asRun(asMachine);

	ASCENE_API_FUNCTION asValue asDebugRun(asMachine);
	ASCENE_API_FUNCTION void asSetDebugFlag(asMachine, asBool);

	//运行ASCENE虚拟机,从指定函数开始运行，运行到该函数返回，返回值为该函数的返回值，若返回NULL表示运行时出现未处理的异常
	//第三个参数是函数的参数数目，以实际传递参数为准；参数传递按照定义顺序的反向进行。这个函数会自动清理栈。
	ASCENE_API_FUNCTION asValue asFunctionRun(asMachine, asString, asInt);

	//运行ASCENE虚拟机,从指定函数句柄开始运行，运行到该函数返回，返回值为该函数的返回值，若返回NULL表示运行时出现未处理的异常
	//第三个参数是函数的参数数目，以实际传递参数为准；参数传递按照定义顺序的反向进行。这个函数会自动清理栈。
	ASCENE_API_FUNCTION asValue asHandleRun(asMachine, asLong, asInt);

	//运行ASCENE虚拟机,以协程方式运行,返回值为main函数的返回值,
	//若返回NULL,则说明运行时出现未处理的异常，
	//若返回 AS_COROUTINE_CONTINUE 则说明协程未完成
	//其他值为main函数完成时的返回值
	//第二参数表示虚拟机最大允许单次运行的字节码长度，0表示无限长
	ASCENE_API_FUNCTION asValue asCoroutineRun(asMachine, int);

	//获得ValuePtr索引的int值
	ASCENE_API_FUNCTION asInt asGetInt(asValue);

	//获得ValuePtr索引的long long值
	ASCENE_API_FUNCTION asLong asGetLong(asValue);

	//获得ValuePtr索引的double值
	ASCENE_API_FUNCTION asDouble asGetDouble(asValue);

	//获得ValuePtr索引的字符串
	ASCENE_API_FUNCTION asString asGetString(asValue);

	//获得ValuePtr索引的成员
	ASCENE_API_FUNCTION asValue asGetMember(asValue, asString);

	//高级功能，用于需要根据一个对象获取其等效弱对象 
	ASCENE_API_FUNCTION void* asGetWeakPtrHwndWithObject(asValue);

	//释放弱对象
	ASCENE_API_FUNCTION void asReleaseWeakPtrHwnd(void*);

	//设置ValuePtr索引的int值
	ASCENE_API_FUNCTION void asSetInt(asValue, asInt);

	//设置ValuePtr索引的long long值
	ASCENE_API_FUNCTION void asSetLong(asValue, asLong);

	//设置ValuePtr索引的double值
	ASCENE_API_FUNCTION void asSetDouble(asValue, asDouble);

	//设置ValuePtr索引的字符串
	ASCENE_API_FUNCTION void asSetString(asValue, asString);

	//用后者向前者赋值
	ASCENE_API_FUNCTION void asSetValue(asValue, asValue);

	//设置ValuePtr索引的变量类型
	ASCENE_API_FUNCTION asEnum asGetType(asValue);

	//显示虚拟机发生的链接错误信息
	ASCENE_API_FUNCTION void asDisplayLinkError(asMachine);

	//显示虚拟机发生的运行时错误信息
	ASCENE_API_FUNCTION void asDisplayRuntimeError(asMachine);

	//获取虚拟机发生的链接错误信息
	ASCENE_API_FUNCTION asString asGetLinkError(asMachine);

	//获取虚拟机发生的运行时错误信息
	ASCENE_API_FUNCTION asString asGetRuntimeError(asMachine);

	//获取虚拟机发生的编译时错误信息
	ASCENE_API_FUNCTION asString asGetCompileError(asMachine);

	//获得ASCENE的版本信息
	ASCENE_API_FUNCTION asString asVersion();

	//获得ASCENE虚拟机内定义的全局变量
	ASCENE_API_FUNCTION asValue asGetPublic(asMachine, asString);


	//向ASCENE虚拟机的栈内内压一个int型的值,返回值为在栈中的该值
	ASCENE_API_FUNCTION asValue asPushInt(asMachine, asInt);

	//向ASCENE虚拟机的栈内内压一个long long型的值,返回值为在栈中的该值
	ASCENE_API_FUNCTION asValue asPushLong(asMachine, asLong);

	//向ASCENE虚拟机的栈内内压一个double型的值,返回值为在栈中的该值
	ASCENE_API_FUNCTION asValue asPushDouble(asMachine, asDouble);

	//向ASCENE虚拟机的栈内内压一个string型的值,返回值为在栈中的该值
	ASCENE_API_FUNCTION asValue asPushString(asMachine, asString);

	//向ASCENE虚拟机的栈内内压入另一个Value,返回值为在栈中的该值
	ASCENE_API_FUNCTION asValue asPushValue(asMachine, asValue);

	//从AScene虚拟机栈中获取数据，第二个参数表示距离，
	//其中，负数表示距离栈顶的距离
	//0和正数表示距离栈底的距离
	ASCENE_API_FUNCTION asValue asStack(asMachine, asInt);

	//从AScene虚拟机栈中弹出一个元素
	ASCENE_API_FUNCTION void asPop(asMachine);

	//向表中注册一个函数，可供ascene虚拟机调用。
	//范例：
	//	asInt SomeFunction(asMachine);
	//	asRegister(SomeFunction,"函数签名字符串");
	//
	//然后在ascene虚拟机内部使用：
	// var someFunction=system::module::gettable("函数签名字符串");
	//此时someFunction就是注册的函数
	ASCENE_API_FUNCTION void asRegister(asInt(*)(asMachine), asString);

	//向表中设置一个值
	ASCENE_API_FUNCTION void asSetTable(asString, asValue);

	//从表中获得一个值
	ASCENE_API_FUNCTION asValue asGetTable(asString);

	//获得一个临时的值
	ASCENE_API_FUNCTION asValue asTempValue();

	//该函数是在AScene C/C++函数内使用的函数，用于获取参数数量。
	ASCENE_API_FUNCTION asLong asArgumentNum(asMachine);

	//该函数是在AScene C/C++函数内使用的函数，用于获取参数。
	ASCENE_API_FUNCTION asValue asArgument(asMachine, asInt);

	ASCENE_API_FUNCTION asString asCopyrightInfo();

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个int型值
	ASCENE_API_FUNCTION asInt asReturnInt(asMachine, asInt);

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个long型值
	ASCENE_API_FUNCTION asInt asReturnLong(asMachine, asLong);

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个double型值
	ASCENE_API_FUNCTION asInt asReturnDouble(asMachine, asDouble);

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个string型值
	ASCENE_API_FUNCTION asInt asReturnString(asMachine, asString);

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个值
	ASCENE_API_FUNCTION asInt asReturnValue(asMachine, asValue);

	//该函数是在AScene C/C++函数内使用的函数，用于给调用方以引用方式返回一个值
	ASCENE_API_FUNCTION asInt asRefReturnValue(asMachine, asValue);

	ASCENE_API_FUNCTION asInt VMStart(asInt argc, char** argv);

	//从arrayHandle指向的AScene数组中获得第index个元素
	ASCENE_API_FUNCTION asValue asArrayGet(asLong arrayHandle, int index);

	//从arrayHandle指向的AScene数组中移除第index个元素
	ASCENE_API_FUNCTION void asArrayErase(asLong arrayHandle, int index);

	//将arrayHandle指向的AScene数组大小设为size
	ASCENE_API_FUNCTION void asArrayResize(asLong arrayHandle, int size);

	//将arrayHandle指向的AScene数组清空
	ASCENE_API_FUNCTION void asArrayClear(asLong arrayHandle);

	//将arrayHandle指向的AScene数组末尾追加元素elem
	ASCENE_API_FUNCTION void asArrayPush(asLong arrayHandle, asValue elem);

	//获得arrayHandle指向的AScene数组的大小
	ASCENE_API_FUNCTION int asArraySize(asLong arrayHandle);

	//获得AScene虚拟机e的运算缓冲寄存器，获取同时会清除寄存器中的引用信息
	ASCENE_API_FUNCTION asValue asMachineCr(asMachine e);

	//获得AScene虚拟机e的Rc寄存器，获取同时会清除寄存器中的引用信息
	ASCENE_API_FUNCTION asValue asMachineRc(asMachine e);

	//根据第二参数给定的虚拟机，复制一个等效虚拟机
	ASCENE_API_FUNCTION void asCopyMachine(asMachine, asMachine);

	//让虚拟机将运行标志置于句柄处
	ASCENE_API_FUNCTION void asSetRunHandle(asMachine, asLong, asInt);

	//根据创建的弱指针索引设置对象
	ASCENE_API_FUNCTION void asSetObjectWithWeakPointer(asValue, void*);

	//抛出异常
	ASCENE_API_FUNCTION void asException(asString exception);

	//将指定的asValue转化为Object，以向其内部填充成员
	ASCENE_API_FUNCTION void asParseObject(asValue value);

	//设置或获取虚拟机路径
	ASCENE_API_FUNCTION asString asVMPath(asString path);

	//添加新的包含路径
	ASCENE_API_FUNCTION void asAddPackagePath(asString path);

	//设置ascene虚拟机在完成编译之后是否需要移除运行时信息以节约内存
	ASCENE_API_FUNCTION void asRemoveRuntimeInfoMode(bool);

	//创建一个AScene变量
	ASCENE_API_FUNCTION asValue asCreateValue();

	//销毁一个AScene变量
	ASCENE_API_FUNCTION void asDestroyValue(asValue);

	//获取一个ascene对象的反射信息句柄
	ASCENE_API_FUNCTION void* asCreateReflactInfo(asValue);

	//销毁一个ascene对象的反射信息
	ASCENE_API_FUNCTION void asDestroyReflactInfo(void*);

	//获取ascene的反射信息，并将访问器向下移动，若访问器已经到底，则返回空指针
	ASCENE_API_FUNCTION asString asReadNextReflactInfo(void*);

#ifdef __cplusplus
}
#endif